#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stropts.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <math.h>
#include <linux/input.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
// #include<time.h>
// #include "sxlb.h"

#define LCD "/dev/ubuntu_lcd"
#define EVENT "/dev/ubuntu_event"
#define SIZE_LCD (800 * 480 * 4)

typedef unsigned int *lcd;
typedef unsigned int uint;
typedef unsigned char uch;

lcd open_lcd(int *lcdfd)
{
    *lcdfd = open(LCD, O_RDWR);
    if (-1 == *lcdfd)
    {
        perror("open err");
        return NULL;
    }
    // printf("设备打开成功\n");

    lcd p = mmap(NULL, SIZE_LCD, PROT_READ | PROT_WRITE, MAP_SHARED, *lcdfd, 0);
    if (MAP_FAILED == p)
    {
        // perror("映射内存失败");
        return NULL;
    }

    // printf("映射成功\n");
    return p;
}

int close_lcd(lcd p, int *lcdfd)
{

    int ret = munmap(p, SIZE_LCD);
    if (-1 == ret)
    {
        // perror("解除映射失败");
    }
    // printf("解除映射成功\n");
    ret = close(*lcdfd);
    if (-1 == ret)
    {
        // perror("关闭设备失败\n");
        return -1;
    }
    // printf("设备已关闭\n");
    return 0;
}

unsigned int Rgb(uint r, uint g, uint b)
{ // 通过设置rgb三种数值调色

    uint rgb = (r << 16) | (g << 8) | b;

    return rgb;
}

void backgroud(uint rgb)
{ // 输入颜色数值打印纯色背景
    int lcdfd = -1;
    lcd p = open_lcd(&lcdfd);

    // 粉色:255,192,203//
    for (int i = 0; i < SIZE_LCD / 4; i++)
    {
        p[i] = rgb;
    }

    close_lcd(p, &lcdfd);
}

void print(int x, int y, const char *picture)
{ // 将图片从坐标(x,y)开始打印
    int bmpfd = open(picture, O_RDONLY);
    if (bmpfd == -1)
    {
        perror("open err");
        return;
    }
    int lcdfd = -1;
    lcd p = open_lcd(&lcdfd);

    uch info[54] = {0};
    read(bmpfd, info, 54);

    // printf("文件标识:%c%c\n",info[0],info[1]);

    uint fSIZE_LCD = (info[5] << 24) | (info[4] << 16) | (info[3] << 8) | (info[2] << 0);
    // printf("文件总大小:%d\n",fSIZE_LCD);

    uint bmp_w = (info[21] << 24) | (info[20] << 16) | (info[19] << 8) | (info[18] << 0);
    uint bmp_h = (info[25] << 24) | (info[24] << 16) | (info[23] << 8) | (info[22] << 0);
    // printf("宽:%d 高:%d \n",bmp_w,bmp_h);

    uch *bmpbuf = (uch *)malloc(bmp_h * bmp_w * 3);
    if (bmpbuf == NULL)
    {
        printf("bmpbuf err\n");
        return;
    }
    read(bmpfd, bmpbuf, bmp_h * bmp_w * 3);

    uint *lcdbuf = (uint *)malloc(bmp_h * bmp_w * sizeof(uint));
    if (lcdbuf == NULL)
    {
        printf("lcdbuf err\n");
        return;
    }

    for (int i = 0; i < bmp_h * bmp_w; i++)
    {
        lcdbuf[i] = (bmpbuf[i * 3 + 0] << 0) | (bmpbuf[i * 3 + 1] << 8) | (bmpbuf[i * 3 + 2] << 16);
    }
    for (int i = y; i < bmp_h + y; i++)
    {
        for (int j = x; j < bmp_w + x; j++)
        {
            if ((j + i * 800) > (800 * 480))
            {
                return;
            }
            if ((j + i * 800) < 0)
            {
                return;
            }

            p[j + i * 800] = lcdbuf[(j - x) + (bmp_h - (i - y) - 1) * bmp_w];
        }
    }

    close_lcd(p, &lcdfd);
    free(bmpbuf);
    free(lcdbuf);
    bmpbuf = NULL;
    lcdbuf = NULL;

    int ret = close(bmpfd);
    if (-1 == ret)
    {
        printf("err\n");
        return;
    }
}

void get_xy(int *x, int *y)
{ // 获取点击的xy值

    // 打开设备
    int tsfd = open(EVENT, O_RDONLY);
    if (-1 == tsfd)
    {
        perror("open err");
        return;
    }

    struct input_event ts;

    while (1)
    {
        // 获取设备事件信息
        int ret = read(tsfd, &ts, sizeof(ts));
        if (-1 == ret)
        {
            perror("read err");
            break;
        }
        if (ts.type == EV_ABS && ts.code == ABS_X)
        {
            *x = ts.value;
        }
        else if (ts.type == EV_ABS && ts.code == ABS_Y)
        {
            *y = ts.value;
            if (*x >= 0)
            {
                break;
            }
        }
    }

    close(tsfd);
}


int keybord(int *x, int *y)
{ // 密码登陆界面的按键反馈

    // 一
    if ((*x) > 452 && (*x) < 536 && (*y) > 80 && (*y) < 145)
    {
        return 1;
    }
    if ((*x) > 556 && (*x) < 642 && (*y) > 80 && (*y) < 145)
    {
        return 2;
    }
    if ((*x) > 663 && (*x) < 745 && (*y) > 80 && (*y) < 145)
    {
        return 3;
    }
    // 二
    if ((*x) > 452 && (*x) < 536 && (*y) > 162 && (*y) < 227)
    {
        return 4;
    }
    if ((*x) > 556 && (*x) < 642 && (*y) > 162 && (*y) < 227)
    {
        return 5;
    }
    if ((*x) > 663 && (*x) < 745 && (*y) > 162 && (*y) < 227)
    {
        return 6;
    }
    // 三
    if ((*x) > 452 && (*x) < 536 && (*y) > 243 && (*y) < 310)
    {
        return 7;
    }
    if ((*x) > 556 && (*x) < 642 && (*y) > 243 && (*y) < 310)
    {
        return 8;
    }
    if ((*x) > 663 && (*x) < 745 && (*y) > 243 && (*y) < 310)
    {
        return 9;
    }
    // 四
    if ((*x) > 452 && (*x) < 536 && (*y) > 323 && (*y) < 390)
    {
        return 10;
    }
    if ((*x) > 556 && (*x) < 642 && (*y) > 323 && (*y) < 390)
    {
        return 0;
    }
    if ((*x) > 663 && (*x) < 745 && (*y) > 323 && (*y) < 390)
    {
        return 11;
    }

    return -1;
}
